﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
 * 版权所有 (c) 2022 北京超维景生物科技有限公司 保留所有权利。
 * CLR版本：4.0.30319.42000
 * 文件名：Kernel
 * 
 * 创建者：huangyang
 * 电子邮箱：huangyang@tvscope.cn
 * 创建时间：2023/2/8 17:51:37
 * 版本：V1.0.0
 * 描述：
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 注 释 >>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ImageK.Java;
using ImageK.Util;

namespace ImageK.IO
{
    public class FileInfo
    {
		/** 8-bit unsigned integer (0-255). */
		public const int GRAY8 = 0;

		/**	16-bit signed integer (-32768-32767). Imported signed images
			are converted to unsigned by adding 32768. */
		public const int GRAY16_SIGNED = 1;

		/** 16-bit unsigned integer (0-65535). */
		public const int GRAY16_UNSIGNED = 2;

		/**	32-bit signed integer. Imported 32-bit integer images are
			converted to floating-point. */
		public const int GRAY32_INT = 3;

		/** 32-bit floating-point. */
		public const int GRAY32_FLOAT = 4;

		/** 8-bit unsigned integer with color lookup table. */
		public const int COLOR8 = 5;

		/** 24-bit interleaved RGB. Import/export only. */
		public const int RGB = 6;

		/** 24-bit planer RGB. Import only. */
		public const int RGB_PLANAR = 7;

		/** 1-bit black and white. Import only. */
		public const int BITMAP = 8;

		/** 32-bit interleaved ARGB. Import only. */
		public const int ARGB = 9;

		/** 24-bit interleaved BGR. Import only. */
		public const int BGR = 10;

		/**	32-bit unsigned integer. Imported 32-bit integer images are
			converted to floating-point. */
		public const int GRAY32_UNSIGNED = 11;

		/** 48-bit interleaved RGB. */
		public const int RGB48 = 12;

		/** 12-bit unsigned integer (0-4095). Import only. */
		public const int GRAY12_UNSIGNED = 13;

		/** 24-bit unsigned integer. Import only. */
		public const int GRAY24_UNSIGNED = 14;

		/** 32-bit interleaved BARG (MCID). Import only. */
		public const int BARG = 15;

		/** 64-bit floating-point. Import only.*/
		public const int GRAY64_FLOAT = 16;

		/** 48-bit planar RGB. Import only. */
		public const int RGB48_PLANAR = 17;

		/** 32-bit interleaved ABGR. Import only. */
		public const int ABGR = 18;

		/** 32-bit interleaved CMYK. Import only. */
		public const int CMYK = 19;

		// File formats
		public const int UNKNOWN = 0;
		public const int RAW = 1;
		public const int TIFF = 2;
		public const int GIF_OR_JPG = 3;
		public const int FITS = 4;
		public const int BMP = 5;
		public const int DICOM = 6;
		public const int ZIP_ARCHIVE = 7;
		public const int PGM = 8;
		public const int IMAGEIO = 9;

		// Compression modes
		public const int COMPRESSION_UNKNOWN = 0;
		public const int COMPRESSION_NONE = 1;
		public const int LZW = 2;
		public const int LZW_WITH_DIFFERENCING = 3;
		public const int JPEG = 4;
		public const int PACK_BITS = 5;
		public const int ZIP = 6;
		public const int ZIP_WITH_DIFFERENCING = 7;

		/* File format (TIFF, GIF_OR_JPG, BMP, etc.). Used by the File/Revert command */
		public int fileFormat;

		/* File type (GRAY8, GRAY_16_UNSIGNED, RGB, etc.) */
		public int fileType;
		public string fileName;
		public string directory;
		public string url;
		public int width;
		public int height;
		public int offset = 0;  // Use getOffset() to read
		public int nImages;
		public int gapBetweenImages;   // Use getGap() to read
		public bool whiteIsZero;
		public bool intelByteOrder;
		public int compression;
		public int[] stripOffsets;
		public int[] stripLengths;
		public int rowsPerStrip;
		public int lutSize;
		public byte[] reds;
		public byte[] greens;
		public byte[] blues;
		public object pixels;
		public string debugInfo;
		public string[] sliceLabels;
		public string info;

        public InputStream inputStream;
		public VirtualStack virtualStack;

		public int sliceNumber; // used by FileInfoVirtualStack

		public double pixelWidth = 1.0;
		public double pixelHeight = 1.0;
		public double pixelDepth = 1.0;
		public string unit;
		public int calibrationFunction;
		public double[] coefficients;
		public string valueUnit;
		public double frameInterval;
		public string description;
		// Use <i>longOffset</i> instead of <i>offset</i> when offset>2147483647.
		public long longOffset;  // Use getOffset() to read
								 // Use <i>longGap</i> instead of <i>gapBetweenImages</i> when gap>2147483647.
		public long longGap;  // Use getGap() to read
							  // Extra metadata to be stored in the TIFF header
		public int[] metaDataTypes; // must be < 0xffffff
		public byte[][] metaData;
		public double[] displayRanges;
		public byte[][] channelLuts;
		public byte[] plot;         // serialized plot
		public byte[] roi;          // serialized roi
		public byte[][] overlay;    // serialized overlay objects
		public int samplesPerPixel;
		public string openNextDir, openNextName;
		public string[] properties; // {key,value,key,value,...}
		public bool imageSaved;

		/** Creates a FileInfo object with all of its fields set to their default value. */
		public FileInfo()
		{
			// assign default values
			fileFormat = UNKNOWN;
			fileType = GRAY8;
			fileName = "Untitled";
			directory = "";
			url = "";
			nImages = 1;
			compression = COMPRESSION_NONE;
			samplesPerPixel = 1;
		}

		/** Returns the file path. */
		public string getFilePath()
		{
            string dir = directory;
			if (dir == null)
				dir = "";
			dir = PathUtil.AddSeparator(dir);
			return dir + fileName;
		}

		/** Returns the offset as a long. */
		public long getOffset()
		{
			return longOffset > 0L ? longOffset : ((long)offset) & 0xffffffffL;
		}

		/** Returns the gap between images as a long. */
		public long getGap()
		{
			return longGap > 0L ? longGap : ((long)gapBetweenImages) & 0xffffffffL;
		}

		/** Returns the number of bytes used per pixel. */
		public int getBytesPerPixel()
		{
			switch (fileType)
			{
				case GRAY8: case COLOR8: case BITMAP: return 1;
				case GRAY16_SIGNED: case GRAY16_UNSIGNED: case GRAY12_UNSIGNED: return 2;
				case GRAY32_INT: case GRAY32_UNSIGNED: case GRAY32_FLOAT: case ARGB: case GRAY24_UNSIGNED: case BARG: case ABGR: case CMYK: return 4;
				case RGB: case RGB_PLANAR: case BGR: return 3;
				case RGB48: case RGB48_PLANAR: return 6;
				case GRAY64_FLOAT: return 8;
				default: return 0;
			}
		}

		public String toString()
		{
			return
				"name=" + fileName
				+ ", dir=" + directory
				+ ", width=" + width
				+ ", height=" + height
				+ ", nImages=" + nImages
				+ ", offset=" + getOffset()
				+ ", gap=" + getGap()
				+ ", type=" + getType()
				+ ", byteOrder=" + (intelByteOrder ? "little" : "big")
				+ ", format=" + fileFormat
				+ ", url=" + url
				+ ", whiteIsZero=" + (whiteIsZero ? "t" : "f")
				+ ", lutSize=" + lutSize
				+ ", comp=" + compression
				+ ", ranges=" + (displayRanges != null ? "" + displayRanges.Length / 2 : "null")
				+ ", samples=" + samplesPerPixel;
		}

		/** Returns JavaScript code that can be used to recreate this FileInfo. */
		public String getCode()
		{
			String code = "fi = new FileInfo();\n";
			String type = null;
			if (fileType == GRAY8)
				type = "GRAY8";
			else if (fileType == GRAY16_UNSIGNED)
				type = "GRAY16_UNSIGNED";
			else if (fileType == GRAY32_FLOAT)
				type = "GRAY32_FLOAT";
			else if (fileType == RGB)
				type = "RGB";
			if (type != null)
				code += "fi.fileType = FileInfo." + type + ";\n";
			code += "fi.width = " + width + ";\n";
			code += "fi.height = " + height + ";\n";
			if (nImages > 1)
				code += "fi.nImages = " + nImages + ";\n";
			if (getOffset() > 0)
				code += "fi.longOffset = " + getOffset() + ";\n";
			if (intelByteOrder)
				code += "fi.intelByteOrder = true;\n";
			return code;
		}

		private string getType()
		{
			switch (fileType)
			{
				case GRAY8: return "byte";
				case GRAY16_SIGNED: return "short";
				case GRAY16_UNSIGNED: return "ushort";
				case GRAY32_INT: return "int";
				case GRAY32_UNSIGNED: return "uint";
				case GRAY32_FLOAT: return "float";
				case COLOR8: return "byte(lut)";
				case RGB: return "RGB";
				case RGB_PLANAR: return "RGB(p)";
				case RGB48: return "RGB48";
				case BITMAP: return "bitmap";
				case ARGB: return "ARGB";
				case ABGR: return "ABGR";
				case BGR: return "BGR";
				case BARG: return "BARG";
				case CMYK: return "CMYK";
				case GRAY64_FLOAT: return "double";
				case RGB48_PLANAR: return "RGB48(p)";
				default: return "";
			}
		}

        public object clone()
        {
            return this.MemberwiseClone();
            //todo:
            // try { return super.clone(); }
            // catch (CloneNotSupportedException e) { return null; }
        }
	}
}
